use header_name::HeaderName;
use headers::HttpHeaders;
use http::{Method, Uri, Version};

pub mod conn;
pub mod header_name;
pub mod header_value;
pub mod headers;
pub mod parse;
pub mod status_code;

#[derive(Debug)]
pub struct Request {
    pub method: Method,
    pub uri: Uri,
    pub version: Version,
    pub headers: HttpHeaders,
}

#[allow(dead_code)]
impl Request {
    pub fn new() -> Self {
        Request {
            method: Method::default(),
            uri: Uri::default(),
            version: Version::default(),
            headers: HttpHeaders::new(),
        }
    }

    pub fn clone(&self) -> Request {
        Request {
            method: self.method.clone(),
            uri: self.uri.clone(),
            version: self.version,
            headers: self.headers.clone(),
        }
    }

    pub fn is_upgrade_req(&self) -> bool {
        self.version >= Version::HTTP_11
            && self.headers.get_header(HeaderName::UPGRADE).is_some()
    }
}

#[derive(Debug)]
pub struct Response {
    pub version: Version,
    pub status_code: u16,
    pub status_reason: String,
    pub headers: HttpHeaders,
}

#[allow(dead_code)]
impl Response {
    pub fn new() -> Self {
        Response {
            version: Version::default(),
            status_code: 0,
            status_reason: "".to_string(),
            headers: HttpHeaders::new(),
        }
    }

    pub fn clear(&mut self) {
        self.version = Version::default();
        self.status_code = 0;
        self.status_reason = "".to_string();
        self.headers = HttpHeaders::new();
    }

    pub fn clone(&self) -> Response {
        Response {
            version: self.version,
            status_code: self.status_code,
            status_reason: self.status_reason.clone(),
            headers: self.headers.clone(),
        }
    }

    pub fn set(&mut self, other: Response) {
        self.version = other.version;
        self.status_code = other.status_code;
        self.status_reason = other.status_reason.clone();

        // 消费other.
        let mut headers = other.headers;
        self.headers.move_headers(&mut headers);
        self.headers = headers;
    }
}
